#!/usr/bin/env ruby

# load the environment (which in turn bootstraps Rails)
base = File.dirname(__FILE__)
require File.join(base, '../../config/environment')

# Method which attempts to save an object
# and reports errors (with line numbers) if they occur.
# 
# Returns the ID of the newly-saved record (will
# be nil if the save fails).
def attempt_save(obj, record_num)
  result = obj.save
  model = obj.class.name
  if result
    puts "#{model} added successfully from record #{record_num} (id = #{obj.id})"
  else
    puts "Problems saving #{model} from record number #{record_num}:"
    obj.errors.each { |_, msg| puts "\t#{msg}" }
  end
  obj.id
end

# MAIN PROCESS

# Read in the TSV file.
File.open(File.join(base, 'contacts.tsv')) do |input|
  # Get the names of the fields (separated by tabs)
  raw_field_names = input.gets.chomp("\n").split("\t")
  
  # Map field names into a hash: keys are field names,
  # values are index positions. Used to reference fields
  # in a row by name, so that positional information is
  # less important.
  field_pos = {}
  field_number = 0
  raw_field_names.map do |field_name|
    field_pos[field_name] = field_number
    field_number += 1
  end
  
  # Process individual records.
  record_num = 1
  while !input.eof
    # Split the row up into individual field values.
    raw = input.gets("\n")
    values = raw.chomp("\n").split("\t")
    
    # Address (company).
    street_1 = values[field_pos['Business Street 1']]
    post_code = values[field_pos['Business Postal Code']]
    
    if c_addr = Address.find_by_street_1_and_post_code(street_1, post_code)
      c_addr_id = c_addr.id
      puts "Using existing company address with id = #{c_addr_id}"
    else
      c_addr = Address.new
      c_addr.street_1 = street_1
      c_addr.street_2 = values[field_pos['Business Street 2']]
      c_addr.street_3 = values[field_pos['Business Street 3']]
      c_addr.city = values[field_pos['Business City']]
      c_addr.county = values[field_pos['Business State']]
      c_addr.post_code = post_code
      c_addr_id = attempt_save(c_addr, record_num)
    end
    
    # Address (personal).
    street_1 = values[field_pos['Home Street']]
    post_code = values[field_pos['Home Postal Code']]
    
    if p_addr = Address.find_by_street_1_and_post_code(street_1, post_code)
      p_addr_id = p_addr.id
      puts "Using existing personal address with id = #{p_addr_id}"
    else
      p_addr = Address.new
      p_addr.street_1 = street_1
      p_addr.street_2 = values[field_pos['Home Street 2']]
      p_addr.street_3 = values[field_pos['Home Street 3']]
      p_addr.city = values[field_pos['Home City']]
      p_addr.county = values[field_pos['Home State']]
      p_addr.post_code = post_code
      p_addr_id = attempt_save(p_addr, record_num)
    end
    
    # Company.
    name = values[field_pos['Company']]
    
    if company = Company.find_by_name(name)
      company_id = company.id
      puts "Using existing company with id = #{company_id}"
    else
      company = Company.new
      company.name = name
      company.fax = values[field_pos['Business Fax']]
      company.telephone = values[field_pos['Company Main Phone']]
      company.telephone ||= values[field_pos['Business Phone']]
      company.website = values[field_pos['Web Page']]
      company.address_id = c_addr_id if c_addr_id
      company_id = attempt_save(company, record_num)
    end
    
    # Person.
    person = Person.new
    person.title = values[field_pos['Title']]
    person.first_name = values[field_pos['First Name']]
    person.last_name = values[field_pos['Last Name']]
    person.job_title = values[field_pos['Job Title']]
    person.telephone = values[field_pos['Home Phone']]
    person.mobile_phone = values[field_pos['Mobile Phone']]
    person.email = values[field_pos['E-mail Address']]
    
    birthday = values[field_pos['Birthday']]
    unless '' == birthday or birthday.nil?
      year, day, month, *_ = ParseDate.parsedate(birthday)
      year += 2000 
      year -= 100 if year > Time.now.year
      birthday = "#{year}-#{month}-#{day}"
    end
    person.date_of_birth = birthday
    
    gender = "M"
    gender = "F" if "female" == values[field_pos["Gender"]]
    person.gender = gender
    
    person.keywords = values[field_pos['Keywords']]
    person.notes = values[field_pos['Notes']]
    
    person.address_id = p_addr_id if p_addr_id
    person.company_id = company_id if company_id
    
    attempt_save(person, record_num)
    
    # Separator
    puts "*" * 30
    
    # Ready for next line
    record_num += 1
  end
end